#! /usr/bin/env python
# encoding: utf-8

"""The Response class provides methods and attributes to set up the outgoing
response.
"""

from datetime import datetime, timedelta
import time

from spyro.internal.httpstatus import HTTPStatus
from spyro.templating.wrapper.jinja2 import Template
from spyro.internal.utils.exceptions import NotFoundException

class Response:
    """
    This class provides the methods to set up the response content.
    The calling method of the Application class will use
    self._status, self._body and self._headers to properly
    set up the WSGI response.
    """

    def __init__(self):
        self._status = HTTPStatus.OK
        self._body = str()
        self._headers = [('Content-Type', 'text/html')]

    def write(self, message):
        """Adds the `message' to the page response body.
        """

        self._body += message

    def from_template(self, template_name, context=dict(), translations=None):
        """Adds the value returned from the template engine and stores it in
        the self._body.
        NOTE: any previous value stored in the self._body will be overwritten.
        """

        self._body = Template(template_name, translations).render(context)

    def set_cookie(self, name, value, path=None, max_age=None,
            life_days=None, life_secs=None, domain=None,
            secure=None, httponly=None):
        """Sets a cookie, creating the string according to the RFC2965.
        Then it appends the cookie to the self._headers list.

        "life_days" is an integer that expresses the expiration in days.
        "life_secs" is the same as above, but more accurate using seconds.
        Note: life_days is preferred over life_secs.
        """

        cookie = "%s=%s" % (name, value)

        # expires
        if life_days is not None:
            expiredate = (datetime.fromtimestamp(time.time()) +
                            timedelta(days=life_days)).strftime(
                                        "%a, %d %b %Y %H:%M:%S +0000")
            cookie += '; Expires=' + expiredate
        elif life_secs is not None:
            expiredate = (datetime.fromtimestamp(time.time()) +
                            timedelta(seconds=life_secs)).strftime(
                                        "%a, %d %b %Y %H:%M:%S +0000")
            cookie += '; Expires=' + expiredate

        # max-age
        if max_age is not None:
            cookie += '; Max-Age=' + max_age
        # path
        if path is not None:
            cookie += '; Path=' + path
        # domain
        if domain is not None:
            cookie += '; Domain=' + domain
        # secure
        if secure is not None:
            cookie += '; Secure'
        # httponly
        if httponly is not None:
            cookie += '; httponly'

        self._headers.append(('Set-Cookie', cookie))

    def delete_cookie(self, name):
        """Deletes a cookie.
        This is done by settings the expiration in the past.
        """

        self.set_cookie(name, '', life_days=-10)

    def redirect(self, url, permanent=False):
        """This method allows you to make a redirect to `url'.
        If permanent is True, will be used the HTTP status code for a Permanent
        Redirect.
        """

        if not permanent:
            self._status = HTTPStatus.Redirect
        else:
            self._status = HTTPStatus.PermanentRedirect

        self._headers.append(('Location', url))

    def not_found(self):
        """Raise a 404 from a controller.
        """

        raise NotFoundException()
